/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       new_map_dialog.h

	$Header: /game/new_map_dialog.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef NEW_MAP_DIALOG_H_INCLUDED
#define NEW_MAP_DIALOG_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#pragma warning( disable: 4786 )

#include <assert.h>
#include <string>

#include "adventure_frame.h"
#include "adventure_map.h"
#include "adventure_map_window.h"
#include "adventure_map_window_ptr.h"
#include "bitmap_layer_window_ptr.h"
#include "button_group.h"
#include "bitmap_group_ptr.h"
#include "cached_ptr.h"
#include "campaign_file_header.h"
#include "counted_ptr.h"
#include "difficulty_level.h"
#include "game_window.h"
#include "map_header.h"
#include "player_setup.h"
#include "scrollbar_ptr.h"
#include "text_window_ptr.h"
#include "toggle_button_ptr.h"

class t_button;
class t_bitmap_group;
class t_bitmap_group_window;
class t_bitmap_layer;
class t_text_edit_window;


struct t_screen_rect;

// ---------------------------------------------------------------------------
// base class representing information about a campaign file or subfolder
// ---------------------------------------------------------------------------

class t_new_map_file_info : public t_counted_object
{
public:
	bool									is_folder() const;
	virtual std::string const &				get_description() const = 0;
	virtual t_campaign_file_header *		get_file_header_ptr() = 0;
	virtual t_campaign_file_header const *	get_file_header_ptr() const = 0;
	virtual std::string const &				get_file_name() const = 0;
	virtual std::string const &				get_loss_condition() const = 0;
	virtual std::string const &				get_name() const = 0;
    virtual int                             get_number_of_maps() const = 0;
	virtual std::string const &				get_victory_condition() const = 0;

private:
	t_map_header const *	get_map_header_ptr() const;
};

inline bool t_new_map_file_info::is_folder() const
{
	return get_file_header_ptr() == 0;
}

typedef t_counted_ptr< t_new_map_file_info > t_new_map_file_info_ptr;

// ---------------------------------------------------------------------------
// line item structure for file list
// ---------------------------------------------------------------------------
struct t_new_map_line
{
	t_text_window_ptr   name_text;
	t_text_window_ptr   size_text;
	t_text_window_ptr   players_text;
	t_text_window_ptr   humans_text;
	t_text_window_ptr   allies_text;
	t_text_window_ptr   map_count_text;

	void set_columns( int name_width, int size, int players, int humans, int allies, 
					  int difficulty, int map_count, int column_width );
};

class t_new_map_dialog;

class t_new_map_item
{
public:
	t_new_map_item( t_new_map_dialog* parent );

	t_window* get_window();
	void      init( t_screen_point point, t_window* parent, t_button_group& group,
		            t_screen_rect rect, int text_x, int line, t_handler_1<int> click_function,
		            t_handler_1<int> double_click_function, int m_column_width );

	void      set( t_new_map_file_info const& file_info );
	void      set_columns( int name_width, int size, int players, int humans, int allies, 
						   int difficulty, int win, int loss, int map_count, 
						   int column_width );
	void      set_highlighted( bool arg = true );
	void      set_visible( bool arg = true );
protected:
	void clicked( t_button* );
	void double_clicked( t_button* );

	int                 m_line_number;
	t_window_ptr        m_normal_window;
	t_window_ptr        m_highlight_window;
	t_new_map_line      m_normal_line;
	t_new_map_line      m_highlight_line;
	t_toggle_button_ptr m_button;
	t_handler_1<int>    m_click_function;
	t_handler_1<int>    m_double_click_function;

	t_bitmap_window_ptr m_difficulty_image;

	t_new_map_dialog*   m_map_dialog;
};

inline t_new_map_item::t_new_map_item( t_new_map_dialog* parent )
{
	m_map_dialog = parent;
}

inline t_window* t_new_map_item::get_window()
{
	return m_normal_window;
}


// ---------------------------------------------------------------------------
// dialog for selecting a new map
// ---------------------------------------------------------------------------
class t_new_map_dialog : public t_window
{
public:
	t_new_map_dialog( t_window* parent );

	t_adventure_map_ptr		get_adventure_map() const;
	t_bitmap_layer const*   get_difficulty_icon( int difficulty ) const;
	t_campaign_file_header& get_file_header();
	std::string             get_file_name();

	bool					showing_difficulty();

protected:
	enum t_sort_order
	{
		k_sort_allies,
		k_sort_difficulty,
		k_sort_humans,
		k_sort_loss,
		k_sort_name,
		k_sort_players,
		k_sort_size,
		k_sort_number_of_maps,
		k_sort_victory,
	};

	void             add_tab( const char* tab_name, std::string const& label, 
		                      std::string const& help_text,
		                      void (t_new_map_dialog::*function)(t_button*), bool pressed );
	void             begin( t_button* button );
	void             cancel( t_button* button );
    void             change_alignment( t_button* button, int position, int delta );
	void			 change_color( t_button* button, int position, int delta );
	void             create_controls();
	t_toggle_button* create_toggle_button( std::string const& name, t_screen_point origin, 
		                                   t_sort_order sort_order, t_window* parent );
	void             file_clicked( int line );
	void             file_double_clicked( int line );
	t_screen_point   find_location( std::string const& layer_name ) const;
	void             file_scroll( t_scrollbar* scrollbar, int line );
	void			 human_checkbox_click( t_button*, int row );
    void             options_decrease_difficulty( t_button* button );
    void             options_increase_difficulty( t_button* button );
	void             read_directory( std::string const& name );
	void             scenario_details( t_button* button );
    void             set_alignment( int row, t_town_type alignment );
    void             set_arrow_color( int position );
	void			 set_color( int row, t_player_color color );
	void             set_columns();
	void             set_highlight( int line );
    void             set_team ( int row, t_player_color color, int team_id = -1 );
	void             set_top_line( int line );
	void             sort_maps( t_button*, t_sort_order sort_order );
    void             turn_duration_scrollbar_move ( t_scrollbar* scrollbar, int value );

	t_adventure_map_ptr					 m_adventure_map_ptr;   // pointer to loaded adventure map
	t_toggle_button_ptr                  m_allies_button;       // sort by # of allies
	t_bitmap_group_ptr			         m_bitmaps;             // all images required for dialog
    t_window_ptr                         m_background;          // overall background
	t_button_ptr                         m_begin_button;        // start game
	int										m_column_width;
	t_toggle_button_ptr					 m_difficulty_button;   // sort by difficulty
	t_bitmap_group_ptr						m_difficulty_bitmaps;
	t_button_group                       m_file_buttons;        // line-item file buttons
	t_button_group                       m_file_columns;        // sort-by buttons
	t_scrollbar_ptr                      m_file_scrollbar;      // scrollbar for file names
	std::string                          m_folder;              // current working folder
	std::vector<t_new_map_file_info_ptr> m_folder_entries;
	t_window_ptr                         m_file_grid;           // background for file names
	t_toggle_button_ptr                  m_humans_button;       // sort by # of humans
	t_toggle_button_ptr                  m_players_button;      // sort by # of players
	t_screen_rect							m_line_rect;
	std::vector<t_new_map_item>          m_lines;               // displayed lines
	t_toggle_button_ptr                  m_loss_button;         // sort by loss conditions
	t_toggle_button_ptr                  m_map_name_button;     // sort by map name
	t_toggle_button_ptr                  m_number_of_maps_button;   // sort by number of maps.
	t_text_window_ptr                    m_scenario_description;
	t_window_ptr                         m_random_map_controls; // all controls in random map pane
	int                                  m_selected_item;       // currently selected map
	bool						         m_show_allies;         // show # of allies
	bool						         m_show_difficulty;     // show difficulty
	bool						         m_show_humans;         // show # of humans
	bool						         m_show_loss;           // show loss conditions
	bool						         m_show_number_of_maps;     // show number of maps
	bool						         m_show_players;        // show # of players
	bool						         m_show_size;           // show map size
	bool						         m_show_victory;        // show victory condition
	t_toggle_button_ptr                  m_size_button;         // sort by map size
	t_sort_order				         m_sort_order;          // current sort order
	t_button_group                       m_tabs;                // map name / options / random tabs
	t_window_list                        m_vertical_lines;      // vertical lines for map names
	t_toggle_button_ptr                  m_victory_button;      // sort by victory conditions
	int                                  m_top_line;            // first visible line
};

inline t_campaign_file_header& t_new_map_dialog::get_file_header()
{
	assert( m_folder_entries[ m_selected_item ]->get_file_header_ptr() != 0 );
	return *m_folder_entries[ m_selected_item ]->get_file_header_ptr();
}

inline 	t_adventure_map_ptr	t_new_map_dialog::get_adventure_map() const
{
	return m_adventure_map_ptr;
}

inline std::string t_new_map_dialog::get_file_name()
{
	return m_folder + m_folder_entries[ m_selected_item ]->get_file_name();
}

inline bool t_new_map_dialog::showing_difficulty()
{
	return m_show_difficulty;
}

#endif // NEW_MAP_DIALOG_H_INCLUDED
